#ifndef _COMMON_H_
#define _COMMON_H_


float steps_to_mm(int pos_steps,int subdiv,float lead,float stepTheta);

int mm_to_steps(float pos_mm,int subdiv,float lead,float stepTheta);

typedef struct _recvDataEleCtl
{
    int sid;
    int frameType;
    union {
        float param_f;
        int param_i;
    }un_param;
}recvDataEleCtl;

typedef struct _eleActCheck
{
    recvDataEleCtl valueDesired;
    unsigned int status;
    struct _eleActCheck * next; 
}eleActCheck;

typedef enum
{
    CHECK_MOVE_END,
    CHECK_RET_BACK_END,
    CHECK_ACT_TIMEOUT,
    CHECK_ACT_ERROR,
}en_check_type;

typedef enum
{
    LUA_ACT_WAITING,
    LUA_ACT_FINISHED,
    LUA_ACT_TIMEOUT,
    LUA_ACT_ERROR,
}en_act_lua_status;

typedef enum
{
	RET_BACK,
	MOVE,
	STOP,
	QUERY,
	PID_CTL,
	MOVE_MM,
	HEAT_CTL,
	MOVE_RELATIVE,
	UIM_MOTOR_INIT,
	SCANCODE_CTL,
    UIM_GOZERO, 
    LIGHT_CTL,   
}EN_SUB_BOARD_OPCODE;


typedef struct _move_param
{
    unsigned char sid;
    unsigned char dir;
    unsigned int speed;
    unsigned int inc_speed;
    unsigned int dec_speed;
    unsigned int pos;
}move_param;



typedef struct _qpcrCtl
{
    unsigned char chanNum;
    unsigned char paramType;
    int paramDataI;
    float paramDataf;
}qpcrCtl;

typedef struct _purifyCtl
{
    unsigned char chanNum;
    unsigned char paramType;
    unsigned char dutyCycle;
    unsigned short rotateSpeedCnt;
    int duration;
}purifyCtl;

typedef struct _capCtl
{
    unsigned char chanNum;
    unsigned char paramType;
    unsigned short delta;
    unsigned short chanMask;
}capCtl;

typedef struct _tecan_tip_param
{   
   int posTip;
   int posRet;
   int speed;
}tecan_tip_param;


typedef struct _tecan_init_param
{   
   int detectType;
}tecan_init_param;

typedef struct _tecan_liquid_param
{
   int posPre;
   int posPost;
   int posMax;
   float quantity; // the unit is uL
   float quanSpitAir1;
   float quanSuckBack;
   int speed;
   unsigned int  delayAfterSpit; // ms
   unsigned int  speedGoUp; // speed when go up back
   float   speedSuckBack;//speed suck back ul/s
}tecan_liquid_param;


typedef struct _pos_dj
{
    int x;
    int y;
    int z;
    int pump;
}pos_dj;

typedef struct _suck_param
{
   int posPre; // the previous position
   int speedPre; // the speed go to previous position
   float air1Quan; // the air quantity before suck liquid
   int speedDetect;// the speed of detecting liquid face
   int threshold; // the threshold of detecting
   int stepBelow;// the step continue to go after detecting success
   float speedSuck;// the suck speed
   float quantity; // the suck quantity
   float more; // the reduntant quantity
   int posMax; //the max pos to go if no liquid 
   int posPost; // the position after sucking finished 
   int speedPost; // the speed to go to posPost
   float air2Quan; // the air quantity after suck liquid    
   float spitQuan; // spit back quantity
   float speedSuckAir1;//ul/s
   int delayAfterSuck; //
   int delayAfterSpit; //
   float speedSuckAir2;//ul/s
   unsigned int spitSpeed;//inc/s
}suck_param;



typedef union _tecanActParam
{
    tecan_tip_param tipParam;
    tecan_liquid_param liquidParam;
    tecan_init_param initParam;
}tecanActParam;

typedef struct _djLiquidCtl
{
    unsigned char chanNum;
    unsigned char paramType;
    unsigned int duration;
}djLiquidCtl;


typedef struct _heatParam
{
    unsigned char heatPlace;
    unsigned char opcode;
    unsigned char chan;
    unsigned char reserved;
    float temperature;
}heatParam;

typedef struct _scancode_param
{
    unsigned char isStart;
    unsigned char chanNum;
}scancode_param;

typedef struct _drawer_lock_param
{
    unsigned char drawerId;
    unsigned char isToLock;
}drawer_lock_param;

typedef struct _temp_read_param
{
    int isStart;
    int interv;
    int chanNum;
}temp_read_param;

typedef enum
{
    HEAT_FOR_HEAT_SEAL,
    HEAT_FOR_SHAKE,
}en_heat_place;


typedef struct _ctl_uim
{
    unsigned char sid;
    unsigned char opcode;
    unsigned char msgSrc;
    union {
        struct {
            unsigned char dir;
            unsigned char ele_index;
            unsigned int position;
            unsigned int queryParam;
            unsigned int speed;
            unsigned int inc_speed;
            unsigned int dec_speed;
        }moveCtl;

        struct {
            int pidChum;
            int pidOpcode;
            float kp;
            float ki;
            float kd;

            float target; 
        }pidCtl;

        struct {
            unsigned char dir;
            unsigned char ele_index;
            float position;
            //unsigned int queryParam;
            float speed;
            float inc_speed;
            float dec_speed;
        }moveCtl_mm;

        qpcrCtl qpcrCtlData;

        tecanActParam tecanCtlData;

        purifyCtl purifyCtlData;
        capCtl capCtlData;

        suck_param suckParam;
        djLiquidCtl djLiquidParam;

        heatParam heatCtlData;

        scancode_param scancodeParam;
        drawer_lock_param drawerLockParam;

        temp_read_param tempReadParam;

    }un_cmd;
    
}ctl_uim;


typedef struct _msg_ctl_uim
{
    long type;
    ctl_uim ctlFrame;
}msg_ctl_uim;

typedef enum
{
   TECAN_Z_MOVE,
   TECAN_LOAD_TIP,
   TECAN_DROP_TIP,
   TECAN_SUCK,
   TECAN_SPIT,
   TECAN_SUCK_EXT,
   TECAN_INIT,
   TECAN_SUCK_P,
   TECAN_RESET,
   TECAN_SUCK_SIMPLE,
   TECAN_SPIT_SIMPLE,
}en_tecan_op;

void getCurrTime(char * timeStrOut);

#define PI 3.1415926

typedef enum
{
    TUBE_BOTTOM_SEMISPHERE,
    TUBE_BOTTOM_CONE,
    TUBE_CUBE_DP8_REAGENT,
}en_bottom_type;

typedef enum
{
    CONTAINER_PCR_BOARD,//cylinder 3.01, cone 12.49, r=2.9mm degree 8.5 12.49/2.9
    CONTAINER_PCR_REAGENT,//cylinder 40, cone 4, r=4.55 degree 4/4.55
    CONTAINER_PU_REAGENT1,//cylinder 11.63, cone 27.37, r=5.15 degree 5.55/27.37
    CONTAINER_PU_SPLIT,//split cylinder r=16.2
    CONTAINER_8TUBE,// cylinder 46.25, semisphere 3.95 r=3.95
    CONTAINER_TUBE_SAMPLE,//cylinder 68.595, semisphere 5.225 
    CONTAINER_PU_REAGENT2,//cylinder 42.04, semisphere 4.025, r=4.025 
}en_container_type;


#define _DEBUG_LOG 1
#define _USE_XML_ 0

extern int flagLiquidCheck;

int volumeToHeight(int volumeIn, int containerType, float* heightOut);

int volumeToHeight_en(int volumeIn, int containerTypeIn, float* heightOut);

typedef struct _volume_height
{
    float volume;
    float height;
}volume_height;

extern int max_num_vh_arr[3];

extern const volume_height vhParam_48holes[];

//extern const volume_height vhParam_pcr_reagent[];

extern const volume_height vhParam_pu_reagent[];

typedef enum
{
   VISCOSITY_LOW,
   VISCOSITY_MIDDLE,
   VISCOSITY_HIGH,
   VISCOSITY_DUMMY,
}en_liquid_viscosity;

#define MAX_LIQUID_CTRL_NUM 6
#define MAX_LIQUID_CTRL_NUM_Q 6

typedef enum
{
   PUMP_OUT_CLEAN = 0,
   PUMP_IN_CLEAN,
   VALVE_IN_CLEAN,
   PUMP_WASTE_LIQUID,
   PUMP_MAG_WASTE_LIQUID=PUMP_WASTE_LIQUID,
   VALVE_WASTE_LIQUID,
   VALVE_IN_CLEAN2,
   PUMP_BOOKED = VALVE_IN_CLEAN2,
   MAX_NUM_PV,
}en_pump_valve;


typedef enum
{
   BARCODE_SCAN_PURIFY_REAGENT,
   BARCODE_SCAN_SAMPLE,
   BARCODE_SCAN_PCR_REAGENT,
   BARCODE_SCAN_CLEAN_REAGENT,        
}en_barcode_scan_id;

typedef enum
{
   I_DRAWER_PCR_BOARD = 0,
   I_DRAWER_PCR_REAGENT1,
   I_DRAWER_PCR_REAGENT2,
   I_DRAWER_RESERVED1,
   I_DRAWER_PURIFY_REAGENT1,
   I_DRAWER_PURIFY_REAGENT2,
   I_DRAWER_RESERVED2,
   I_DRAWER_RESERVED3,
   I_DRAWER_SAMPLE1,
   I_DRAWER_SAMPLE2,
   I_DRAWER_SAMPLE3,
   I_DRAWER_SAMPLE4,
   I_DRAWER_DP8TIPS1,
   I_DRAWER_DP8TIPS2,
   I_DRAWER_HEAT_FILM,
   I_DRAWER_RESERVED4,
   MAX_I_DRAWER,
}en_index_drawer;

typedef enum
{
	I_DOOR_PCR_REAGENT1,
    I_DOOR_PCR_REAGENT2,
    I_DOOR_PURIFY_AREA1,
	I_DOOR_PURIFY_AREA2,
	I_DOOR_PURIFY_UP,
	I_DOOR_PURIFY_DOWN,
	I_DOOR_QPCR1,
	I_DOOR_QPCR2,
	MAX_I_DOOR
}en_door_index;

#define FILE_BARCODE_PATH "/mnt/nandflash/apps/tmp/"

#define FILE_QPCR_SCHEME_PATH FILE_BARCODE_PATH

#endif
